﻿/******************************************************************************
 *  Project:		Neddle Community Edition
 *  Filename:		DateTimeExtensions.cs
 *	Created By:     Kristopher Cargile <kristopher@neddle.org>
 *  Date Created:	March 29, 2011
 * ****************************************************************************
 * IMPORTANT GNU LICENSE INFORMATION. DO NOT REMOVE THIS SECTION!
 * 
 * Neddle :: Copyright (c) 2010-2012, Cargile Technology Group, LLC
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 ******************************************************************************/

using System;

namespace Neddle 
{
    /// <summary>
    /// DateTimeExtensions
    /// </summary>
    public static class DateTimeExtensions
    {
        /// <summary>
        /// Remove milliseconds from date passed in.
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public static DateTime RemoveMilliseconds(this DateTime parm)
        {
            return new DateTime(parm.Year, parm.Month, parm.Day, parm.Hour, parm.Minute, parm.Second);
        }

        /// <summary>
        /// Get the date of the last day of the month for the date passed in.
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public static DateTime GetLastDateOfTheMonth(this DateTime parm)
        {
            DateTime nextMonth = parm.AddMonths(1);
            nextMonth = new DateTime(nextMonth.Year, nextMonth.Month, 1);
            return nextMonth.AddDays(-1);
        }

        /// <summary>
        /// Gets the last date of the month.
        /// </summary>
        /// <param name="parm">The parm.</param>
        /// <returns></returns>
        public static DateTime? GetLastDateOfTheMonth(this DateTime? parm)
        {
            if (parm == null)
            {
                return null;
            }

            return parm.Value.GetLastDateOfTheMonth();
        }


        /// <summary>
        /// Get the date of the first day of the month for the date passed in.
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public static DateTime GetFirstDateOfTheMonth(this DateTime parm)
        {
            return new DateTime(parm.Year, parm.Month, 1);
        }

        /// <summary>
        /// Get the date of the first day of the month for the date passed in.
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public static DateTime? GetFirstDateOfTheMonth(this DateTime? parm)
        {
            if (parm == null)
            {
                return null;
            }

            return new DateTime(parm.Value.Year, parm.Value.Month, 1);
        }

        /// <summary>
        /// Get a <see cref="DateTime"/> for the very end of the day
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public static DateTime GetEndOfDay(this DateTime parm)
        {
            // if input is last recognized day in the eyes of .net, use max time of eternity
            if (parm >= DateTime.MaxValue.Date)
            {
                return DateTime.MaxValue;
            }
            // otherwise, use the last few milliseconds of today

            // HACK: subtract 4 milliseconds instead of 1 to prevent rounding up to the next
            // day when going to our persistent store <cough>sql server</cough>
            // http://msdn.microsoft.com/en-us/library/ms187819(SQL.90).aspx
            return parm.Date.AddDays(1).AddMilliseconds(-4);
        }
    }
}
